package algotradingfx.strategies;

import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import algotradingfx.data.TickWriter;
import algotradingfx.utils.Constants;
import algotradingfx.utils.FXAsset;
import atp.client.trading.strategies.StrategyPush;
import atp.commons.util.StrategyInfo;
import atp.commons.util.Tick;

public class TickerPlant extends StrategyPush {
	public static Logger LOGGER = Logger.getLogger(TickerPlant.class);

	private static final long serialVersionUID = 1728280496562117242L;

	private static final String STRATEGY_NAME = "TickerPlant";
	private static final String PATH = "src/algotradingfx/data/";
	private static final String ALL_TICKS_FILE_NAME = "ALLTICKS";
	private TickWriter allTicksWriter;
	private Map<FXAsset, TickWriter> tickWriterMap;
	private Map<FXAsset, Tick> lastTickMap;

	public TickerPlant(String ssID, String password) {
		super(new StrategyInfo(STRATEGY_NAME), ssID, password);
	}

	@Override
	public void initialise() {
		try {
			tickWriterMap = new HashMap<FXAsset, TickWriter>();
			lastTickMap = new HashMap<FXAsset, Tick>();
			for (FXAsset asset : FXAsset.values()) {
				// add all assets to the files
				declare(asset.toString(), Constants.MOCK_BROKER);
				tickWriterMap.put(asset, new TickWriter(new FileWriter(asset
						.toString(), true)));
				tickWriterMap.put(asset, new TickWriter(new FileWriter(asset
						.toString(), true)));
				lastTickMap.put(asset, new Tick());

			}
			allTicksWriter = new TickWriter(new FileWriter(ALL_TICKS_FILE_NAME,
					true));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void finalize() throws Throwable {
		try {
			for (FXAsset asset : tickWriterMap.keySet()) {
				tickWriterMap.get(asset).close();
			}
			allTicksWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			super.finalize();
		}
	}

	@Override
	public boolean run(Object o) {
		try {
			if (o instanceof Tick) {
				Tick t = (Tick) o;
				FXAsset asset = FXAsset.valueOf(t.getSymbol());
				// check if any change
				Tick lastTick = lastTickMap.get(asset);
				allTicksWriter.writeTick(t);
				if (hasTickChanged(t, lastTick)) {
					lastTickMap.put(asset, t);
					tickWriterMap.get(asset).writeTick(t);
				}
				// LOGGER.debug(allTicksWriter.toString(t));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	private boolean hasTickChanged(Tick t1, Tick t2) {
		return ((t1.getAsk() != t2.getAsk()) || (t1.getBid() != t2.getBid())
				|| (t1.getAskDepth() != t2.getAskDepth())
				|| (t1.getBidDepth() != t2.getBidDepth()) || (t1.getSpread() != t2
				.getSpread()));
	}
}
